Skip to content

Conversation

@brandur
Copy link
Contributor

@brandur brandur commented Dec 24, 2025

Here, add a contrib package called versionedjob that brings in a very
basic job versioning framework. The framework is very lightweight and
users could easily have written it themselves, but it might be a little
non-obvious how to leverage hooks to bring it in.

Contrib should be a really nice home for this feature because it's a
little too trivial to bother with in core, but it's nice for people to
have a semi-official reference that's well-maintained.

@brandur brandur force-pushed the brandur-versioned-job branch from 83512d6 to be6ba5e Compare December 24, 2025 23:35
Copy link

@diegobernardes diegobernardes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚀

@brandur brandur force-pushed the brandur-versioned-job branch from be6ba5e to 13d81f2 Compare December 28, 2025 22:43
Here, add a contrib package called `versionedjob` that brings in a very
basic job versioning framework. The framework is very lightweight and
users could easily have written it themselves, but it might be a little
non-obvious how to leverage hooks to bring it in.

Contrib should be a really nice home for this feature because it's a
little too trivial to bother with in core, but it's nice for people to
have a semi-official reference that's well-maintained.
@brandur brandur force-pushed the brandur-versioned-job branch from 13d81f2 to aab9fad Compare December 28, 2025 22:43
@brandur
Copy link
Contributor Author

brandur commented Dec 28, 2025

Nice.

@bgentry Want to take a look at this too? Might make a good blog post at least.

@brandur brandur requested a review from bgentry December 28, 2025 22:44
Copy link
Contributor

@bgentry bgentry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like one good way to do this! Another is to implement a custom UnmarshalJSON on your arg type.

}
```

The `VersionTransformer` implementation handles version upgrades one by one. Jobs which are multiple versions old can still be upgraded because multiple version changes can be applied in one go. This implementation uses `gjson`/`sjson` so that each change need only know a minimum about the data object in question and that unknown fields are retained. Other approaches are possible though, including using only Go's built-in `gjson` package.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume you meant encoding/json?

Suggested change
The `VersionTransformer` implementation handles version upgrades one by one. Jobs which are multiple versions old can still be upgraded because multiple version changes can be applied in one go. This implementation uses `gjson`/`sjson` so that each change need only know a minimum about the data object in question and that unknown fields are retained. Other approaches are possible though, including using only Go's built-in `gjson` package.
The `VersionTransformer` implementation handles version upgrades one by one. Jobs which are multiple versions old can still be upgraded because multiple version changes can be applied in one go. This implementation uses `gjson`/`sjson` so that each change need only know a minimum about the data object in question and that unknown fields are retained. Other approaches are possible though, including using only Go's built-in `encoding/json` package.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thx.

@brandur brandur merged commit ad75de2 into master Jan 18, 2026
5 checks passed
@brandur brandur deleted the brandur-versioned-job branch January 18, 2026 20:22
@brandur
Copy link
Contributor Author

brandur commented Jan 18, 2026

Seems like one good way to do this! Another is to implement a custom UnmarshalJSON on your arg type.

I think one reason you might want to do this separately is that eventually all non-trivial version transformations tend to involved fetching data from the DB (this is what happened at Stripe anyway), so you probably want to have a struct you can add a DB pool to and access to ctx.

This is definitely something to make clear in an eventual blog post though.

brandur added a commit that referenced this pull request Jan 18, 2026
Prepare a periodic release for rivercontrib. This largely contains a new
lightweight version change framework as seen in #39.
@brandur brandur mentioned this pull request Jan 18, 2026
brandur added a commit that referenced this pull request Jan 18, 2026
Prepare a periodic release for rivercontrib. This largely contains a new
lightweight version change framework as seen in #39.

[skip ci]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants